package com.yinp.proapp.module.baidu_map.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.baidu.location.Address;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.sug.SuggestionResult;
import com.baidu.mapapi.search.sug.SuggestionSearch;
import com.baidu.mapapi.search.sug.SuggestionSearchOption;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.XXPermissions;
import com.yinp.proapp.R;
import com.yinp.proapp.base.activity.AppBaseActivity;
import com.yinp.proapp.constant.Constant;
import com.yinp.proapp.databinding.ActivityBaiduMapBinding;
import com.yinp.proapp.module.baidu_map.other.MyOrientationListener;
import com.yinp.proapp.utils.AppUtils;
import com.yinp.proapp.utils.BaiduMapUtils;
import com.yinp.proapp.utils.GPS_Presenter;
import com.yinp.proapp.utils.LocationHelper;
import com.yinp.proapp.utils.NetChangeReceiver;
import com.yinp.proapp.utils.NetUtil;
import com.yinp.proapp.utils.StatusBarUtil;
import com.yinp.proapp.view.PermissionDialog;
import com.yinp.tools.fragment_dialog.BaseDialogFragment;
import com.yinp.tools.fragment_dialog.CommonDialogFragment;
import com.yinp.tools.fragment_dialog.DialogFragmentHolder;
import com.yinp.tools.fragment_dialog.ViewConvertListener;

import java.util.ArrayList;
import java.util.List;

public class BaiduMapActivity extends AppBaseActivity<ActivityBaiduMapBinding> implements GPS_Presenter.GPS_Interface, NetChangeReceiver.NetChangeListener {
    private BaiduMap mBaiduMap;
    private String address;
    private GPS_Presenter gps_presenter;//gps监听
    private Address mAddress;
    private LatLng point;
    //搜索相关
    private SuggestionSearch mSuggestionSearch;
    //是否能够使用
    private boolean isCanUse = false;


    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void initViews() {
        setStatusBarHeight(StatusBarUtil.getStatusBarHeight(mContext));
        bd.header.headerCenterTitle.setText("地图");
        checkLocation();
        initClick(bd.header.headerBackImg, bd.tvSearch);
        mBaiduMap = bd.bmapView.getMap();
        //默认点为成都市
        BaiduMapUtils.moveToLatLng(mBaiduMap, new LatLng(30.579003362342146, 104.0727267028659));
        initMap();
    }

    @Override
    public void onClick(View v) {
        super.onClick(v);
        if (v == bd.tvSearch) {
//            search();
            Bundle bundle = new Bundle();
            goToActivity(BaiduMapSearchActivity.class, bundle, Constant.REQUEST_CODE);
        } else if (v == bd.header.headerBackImg) {
            finish();
        }
    }

    /**
     * 权限申请
     */
    private void checkLocation() {
        XXPermissions.with(this)
                .permission(Manifest.permission.ACCESS_FINE_LOCATION) //不指定权限则自动获取清单中的危险权限
                .request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        if (all) {
                            isCanUse = true;
                        }
                    }

                    @Override
                    public void onDenied(List<String> permissions, boolean never) {
                        if (never) {
                            isCanUse = false;
                            bd.tvSearch.setHint("没有定位权限，一部分功能将无法使用");
                            PermissionDialog permissionDialog = new PermissionDialog(mActivity, getString(R.string.per_tips, getString(R.string.location)), permissions);
                            permissionDialog.show();
                        }
                    }
                });
    }

    /**
     * 搜索
     */
    private void search() {
        if (TextUtils.isEmpty(bd.tvSearch.getText().toString())) {
            return;
        }
        mSuggestionSearch = SuggestionSearch.newInstance();
        mSuggestionSearch.setOnGetSuggestionResultListener(suggestionResult -> {
            //处理sug检索结果
            SuggestionResult.SuggestionInfo ss = suggestionResult.getAllSuggestions().get(0);
            //将改点移动到屏幕中心
            point = ss.getPt();
            //移动地图到指定位置
            BaiduMapUtils.moveToLatLng(mBaiduMap, point);
            address = ss.address + "-" + ss.city;
            if (isCanUse) {
                drawPointIcon();
                locationDialog();
            }
        });
        /**
         * 在您的项目中，keyword为随您的输入变化的值
         */
        if (mAddress != null) {
            mSuggestionSearch.requestSuggestion(new SuggestionSearchOption()
                    .city(mAddress.city)
                    .keyword(bd.tvSearch.getText().toString()));
        } else {
            mSuggestionSearch.requestSuggestion(new SuggestionSearchOption()
                    .city("中国")
                    .keyword(bd.tvSearch.getText().toString()));
        }
    }

    private void initMap() {
        MapStatus.Builder builder = new MapStatus.Builder();
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        //普通地图 ,mBaiduMap是地图控制器对象
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        //开启地图的定位图层
        mBaiduMap.setMyLocationEnabled(true);
        //设置地图单击事件监听
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            /**
             * 地图单击事件回调函数
             *
             * @param point 点击的地理坐标
             */
            @Override
            public void onMapClick(LatLng point) {
                if (isCanUse) {
                    BaiduMapActivity.this.point = point;
                    drawPointIcon();
                    getClickAddress();
                }
            }

            /**
             * 地图内 Poi 单击事件回调函数
             *
             * @param mapPoi 点击的 poi 信息
             */
            @Override
            public void onMapPoiClick(MapPoi mapPoi) {
                if (isCanUse) {
                    address = mapPoi.getName();
                    point = mapPoi.getPosition();
                    locationDialog();
                }
            }
        });
        //自定义当前位置图标样式
        if (isCanUse) {
            BaiduMapUtils.setCurLocationIcon(mBaiduMap);
        }

        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (gps) {
            //初始化当前位置信息
            initLocationClient();
        } else {
            BaiduMapUtils.moveToLatLng(mBaiduMap, new LatLng(30.579003362342146, 104.0727267028659));
            Toast.makeText(this, "手机GPS已关闭,打开才能定位当前位置", Toast.LENGTH_LONG).show();
        }
    }

    private LocationHelper locationHelper;

    /**
     * 初始化得到当前位置的信息
     */
    public void initLocationClient() {
        if (!isCanUse) {
            return;
        }
        locationHelper = new LocationHelper(this);
        locationHelper.setCallBack(bdLocation -> {
            //mapView 销毁后不在处理新接收的位置
            if (bdLocation == null || bd.bmapView == null) {
                return;
            }
            if (bdLocation.getLocType() == 63) {
                showToast("请确认当前测试手机网络是否通畅");
                return;
            }
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(bdLocation.getRadius())
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            mCurrentAccracy = bdLocation.getRadius();
            if (bdLocation.getLatitude() == 4.9E-324 && bdLocation.getLongitude() == 4.9E-324) {
                point = new LatLng(30.579003362342146, 104.0727267028659);
            } else {
                point = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
                mAddress = bdLocation.getAddress();
                mBaiduMap.setMyLocationData(locData);
            }
            initOritationListener();
            myOrientationListener.start();
            //移动地图到指定位置
            BaiduMapUtils.moveToLatLng(mBaiduMap, point);
        });
        locationHelper.start();
    }

    MyOrientationListener myOrientationListener;
    float mCurrentAccracy;

    /**
     * 初始化方向传感器
     */
    private void initOritationListener() {
        myOrientationListener = new MyOrientationListener(getApplicationContext());
        myOrientationListener.setOnOrientationListener(x -> {
            int mXDirection = (int) x;
            // 构造定位数据
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(mCurrentAccracy)
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(mXDirection)
                    .latitude(point.latitude)
                    .longitude(point.longitude)
                    .build();
            // 设置定位数据
            mBaiduMap.setMyLocationData(locData);
            //覆盖后的图片儿无法旋转，原因未知
            BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory.fromResource(R.mipmap.jianjian);
            MyLocationConfiguration config = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, null);
            mBaiduMap.setMyLocationConfiguration(config);
        });
    }

    /**
     * 获取点击选中的地址信息
     */
    public void getClickAddress() {
        //实例化一个地理编码查询对象
        GeoCoder geoCoder = GeoCoder.newInstance();
        OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {
            @Override
            public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
            }

            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
                if (reverseGeoCodeResult == null || reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
                    //没有找到检索结果
                    return;
                } else {
                    //详细地址
                    address = reverseGeoCodeResult.getAddress() + reverseGeoCodeResult.getSematicDescription();
                    LatLng mpoint = reverseGeoCodeResult.getLocation();
                    point = mpoint;
                    locationDialog();
                }
            }
        };
        geoCoder.setOnGetGeoCodeResultListener(listener);
        geoCoder.reverseGeoCode(new ReverseGeoCodeOption()
                .location(point)
                // 设置是否返回新数据 默认值0不返回，1返回
                .newVersion(1)
                // POI召回半径，允许设置区间为0-1000米，超过1000米按1000米召回。默认值为1000
                .radius(500));
        geoCoder.destroy();
    }

    /**
     * 绘制所选择的点
     */
    private List<Overlay> list = new ArrayList<>();

    private void drawPointIcon() {
        //定义Maker坐标点
//        LatLng point = new LatLng(39.963175, 116.400244);
        mBaiduMap.removeOverLays(list);
//构建Marker图标
        BitmapDescriptor bitmap = BitmapDescriptorFactory
                .fromResource(R.mipmap.select_location);
//构建MarkerOption，用于在地图上添加Marker
        OverlayOptions option = new MarkerOptions()
                .position(point)
                .icon(bitmap);
//在地图上添加Marker，并显示
        list.add(mBaiduMap.addOverlay(option));
    }

    public void locationDialog() {
        if (1 > 0) {
            return;
        }
        CommonDialogFragment.newInstance().setLayoutId(R.layout.dialog_tips).setViewConvertListener(new ViewConvertListener() {
            @Override
            public void convertView(DialogFragmentHolder holder, BaseDialogFragment dialogFragment) {

            }
        }).setGravity(BaseDialogFragment.BOTTOM).setAnimStyle(R.style.BottomDialogAnimation).setPercentSize(AppUtils.getWidth()
                , AppUtils.dpToPx(0)).show(getSupportFragmentManager());
    }

    /**
     * 对返回的搜索条件进行搜索
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 位置信息是否打开
     *
     * @param
     */
    @Override
    public void gpsSwitchState(boolean gpsOpen) {
        if (gpsOpen) {
            initLocationClient();
        } else {
            BaiduMapUtils.moveToLatLng(mBaiduMap, new LatLng(30.579003362342146, 104.0727267028659));
            Toast.makeText(this, "手机GPS已关闭,打开才能定位当前位置", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onChangeListener(int status) {
        if (status == NetUtil.NETWORK_NONE) {
            Toast.makeText(this, "请确认当前测试手机网络是否打开", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onResume() {
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        bd.bmapView.onResume();
        super.onResume();
        if (myOrientationListener != null) {
            myOrientationListener.start();
        }
    }

    @Override
    protected void onPause() {
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        bd.bmapView.onPause();
        if (myOrientationListener != null) {
            myOrientationListener.stop();
        }
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        if (gps_presenter != null) {
            gps_presenter = null;
        }
        if (mBaiduMap != null) {
            mBaiduMap.setMyLocationEnabled(false);
        }
        if (locationHelper != null) {
            locationHelper = null;
        }
        if (bd.bmapView != null) {
            bd.bmapView.onDestroy();
        }
        if (mSuggestionSearch != null) {
            mSuggestionSearch.destroy();
        }
        mAddress = null;
        super.onDestroy();
    }
}